const Header = require('./headers');
const url = require('url');
const Body = require('./body');
const qs = require('querystring');
const Stream = require('stream');

function matchContentType(body) {
  if (body == null) {
    return null;
  }
  else if (typeof body === 'string') { // string
    return 'text/plain;charset=UTF-8';
  }
  else if (body instanceof url.URLSearchParams) { // URLSearchParams
    return 'application/x-www-form-urlencoded;charset=UTF-8';
  }
  else if (Buffer.isBuffer(body)) { // buffer
    return null;
  }
  else if (body instanceof ArrayBuffer) { // ArrayBuffer
    return null;
  }
  else if (typeof body.getBoundary === 'function') { // form-data
    return `multipart/form-data;boundary=${body.getBoundary()}`;
  }
  else if (body instanceof Stream) { // Stream
    return null;
  }
  else { // Body constructor defaults other things to string
    return 'application/x-www-form-urlencoded;charset=UTF-8';
  }
}

class Request extends Body {
  constructor(input, init) {
    super();
    init = init || {};
    let body = init.body;
    this.bodyUsed = false;
    if (input instanceof Request) {
      if (input.bodyUsed) {
        throw new TypeError('Already read');
      }
      this.url = input.url;
      if (!input.headers) {
        this.headers = new Header(input.headers);
      }
      if (!body && input.body != null) {
        this.body = input.body;
        input.bodyUsed = true;
      }
      this.auth = input.auth || null;
      this.agent = input.agent || null;
      this.createConnection = input.createConnection || null;
      this.timeout = input.timeout || 0;
    }
    else {
      this.url = new url.URL(input);
    }
    if (init.headers || !this.headers) {
      this.headers = new Header(init.headers);
    }
    this.method = (init.method || this.method || 'GET').toUpperCase();
    if (body) { // 传递了 body 参数
      if (this.method === 'HEAD') {
        throw new TypeError('Body not allowed for HEAD requests');
      }
      else if (this.method === 'GET') {
        if (typeof body === 'string') {
          this.url += '?' + body;
        }
        else {
          this.url += '?' + qs.stringify(body);
        }
      }
    }
    if (this.method === 'GET') {
      this._defaultHeaders(null);
      this._initBody(null);
    }
    else {
      this._defaultHeaders(body);
      this._initBody(body);
    }
    this.auth = init.auth || this.auth;
    this.agent = init.agent || this.agent;
    this.createConnection = init.createConnection || this.createConnection;
    this.timeout = init.timeout || this.timeout;
  }
  clone() {
    return new Request(this, { body: this.body });
  }
  // 添加一些初始化的 headers
  _defaultHeaders(body) {
    if (!this.headers.has('Accept')) {
      this.headers.set('Accept', '*/*');
    }
    if (!(this.headers.has('Accept-Encoding'))) {
      this.headers.set('Accept-Encoding', 'gzip,deflate');
    }
    // Content-Type
    if (!this.headers.has('Content-Type')) {
      let exactContentType = matchContentType(body);
      if (exactContentType) {
        this.headers.set('Content-Type', exactContentType);
      }
    }
  }
}

module.exports = Request;
